﻿﻿using System;
 using System.Collections;
 using Com.Enemy.EnemySystem.Tools;
 using Script.EnemySystem.Tools;
 using UnityEngine;
 using UnityEngine.Events;

 namespace Com.Enemy.EnemySystem.EnemyLifecycle
{
    /// <summary>
    ///  怪物生命周期
    /// </summary>
    public class EnemyBody : MonoBehaviour
    {
        [SerializeField] private Data form;
        [SerializeField] private Transform target;
        [SerializeField] protected float playerCheckRadius;

        public Transform Target => target;
        public Rigidbody2D Rb { get; private set; }
        public CoolDownSystem CoolDownSystem { get; } = new CoolDownSystem();

        private Material material;
        
        private static readonly int ColorR = Shader.PropertyToID("_ColorR");
        public bool IsPlayerInArea
        {
            get;
            set;
        }

        public EnemyData Data
        {
            get;
            set;
        }

        private void Awake()
        {
            Rb = GetComponent<Rigidbody2D>();
            Data = new EnemyData(form.hp, form.maxHealth, form.moveSpeed, form.followSpeed,form.damage, form.rangedAttackDistance, form.meleeAttackDistance, form.backInterpolation ,form.localTimeScale);
        }

        private void Start()
        {
            material = GetComponent<SpriteRenderer>().material;
        }

        private void Update()
        {
            StartCoroutine(CoolDownSystem.UpdateColdDown(Data.TimeData));
        }

        private void FixedUpdate()
        {
            CheckPlayer();
        }
        
        /// <summary>
        /// 搜索玩家
        /// </summary>
        public void CheckPlayer()
        {
            Collider2D collider2D = Physics2D.OverlapCircle(transform.position, playerCheckRadius, LayersTools.Player);
            
            IsPlayerInArea = collider2D;
        }

        /// <summary>
        /// 伤害计算
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="damage"></param>
        /// <param name="force"></param>
        public void TakeDamage(int playerId, float damage, float force)
        {
            if (Data.Hp - damage > 0)
            {
                Data.Hp -= new BaseData(damage);
                StopCoroutine(HurtReaction(force));
                StartCoroutine(HurtReaction(force));
            }
            else
            {
                
            }
            EventManager.Broadcast(EventName.Enemy.TakeDamage, playerId, damage, force);
        }

        public IEnumerator HurtReaction(float force, bool isFlash = true)
        {
            
            yield return new WaitForSeconds(.1f);
            
            Vector3 backTo = (transform.position - target.position).normalized;
            

            float time = 0;

            while (time < .1f)
            {
                
                Rb.velocity = backTo * (force * Time.fixedDeltaTime);
                if(isFlash)
                    material.SetFloat(ColorR, 1);
                
                yield return new WaitForSeconds(Time.fixedDeltaTime);
                
                Rb.velocity = Vector2.zero;
                if(isFlash)
                    material.SetFloat(ColorR, 0);

                time += Time.fixedDeltaTime;
            }
            
        }
        

#if UNITY_EDITOR
        private void OnDrawGizmos()
        {
            Gizmos.color = Color.yellow;
            if (Data != null)
            {
                var position = transform.position;
                Gizmos.DrawWireSphere(position, Data.MeleeAttackDistance);
                Gizmos.DrawWireSphere(position, Data.RangedAttackDistance);
            }
            Gizmos.DrawWireSphere(transform.position, playerCheckRadius);

        }
#endif
        
    }

    [Serializable]
    struct Data
    {
        public float maxHealth;
        public float hp;
        public float moveSpeed;
        public float followSpeed;
        public float damage;
        public float meleeAttackDistance;
        public float rangedAttackDistance;
        public float backInterpolation;
        public float localTimeScale;
    }
    
    
}
